﻿
using DataService.Core.ServiceDTO;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DataService.IService
{
    public interface IRemoteDB
    {
        /// <summary>链接字符串</summary>
        String ConnectionString { get; set; }
        /// <summary>模型文件路径</summary>
        String ModeFilePath { get; set; }
        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <returns>添加条数</returns>
        int Insert<T>(T t, string suffix, DbConnection conn, DbTransaction tran);
        /// <summary>
        /// 批量插入；使用参数化
        /// </summary>
        int Insert<T>(IList<T> t, string suffix, DbConnection conn, DbTransaction tran);
        /// <summary>
        /// 批量添加
        /// </summary>
        ///<returns>添加条数</returns>
        int BeatchInsert<T>(IList<T> t, string suffix, DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 更新一条数据（默认更新所有字段）
        /// </summary>
        /// <returns>更新条数</returns>
        int Update<T>(T t, string suffix, DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 更新一条数据
        /// </summary>
        /// <param name="fieldFunc">需要更新的字段，例：x=>new{x.字段1, x.字段2}</param>
        /// <returns>更新条数</returns>
        int Update<T>(T t, Expression<Func<T, object>> fieldFunc, string suffix, DbConnection conn, DbTransaction tran);


        /// <summary>
        /// 批量更新
        /// </summary>
        /// <returns>更新条数</returns>
        int BeatchUpdate<T>(IEnumerable<T> t, string suffix, DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="fieldFunc">需要更新的字段</param>
        /// <returns>更新条数</returns>
        int BeatchUpdate<T>(IEnumerable<T> t, Expression<Func<T, object>> fieldFunc, string suffix, DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 删除数据
        ///支持In查找
        /// Guid[] tempArray=new Guid[]{值1,值2}
        /// string[] tempArray=new string[]{值1,值2}
        /// 例：Update<T>(x => tempArray.Contains(x.字段)|| tempArray1.Contains(x.字段));
        /// </summary>
        /// <param name="whereFunc">where条件，例：x=>new{x.字段5, x.字段6</param>
        /// <returns>删除条数</returns>
        int Delete<T>(Expression<Func<T, bool>> whereFunc, string suffix, DbConnection cnn, DbTransaction tran);


        DataTable QueryDataTable(string sql, Dictionary<string, object> dic, DbConnection conn, DbTransaction tran);
        /// <summary>
        /// 返回单行单列的值，支持In查找
        /// Guid[] tempArray=new Guid[]{值1,值2}
        /// string[] tempArray=new string[]{值1,值2}
        /// 例：Scalar<T>(x => tempArray.Contains(x.字段)|| tempArray1.Contains(x.字段));
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereFunc">where条件，例：x=>new{x.字段5, x.字段6</param>
        /// <param name="cnn"></param>
        /// <param name="commandTimeout"></param>
        /// <param name="commandType"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        int ScalarCount<T>(Expression<Func<T, bool>> whereFunc, string suffix, DbConnection cnn, DbTransaction tran, int? commandTimeout, CommandType? commandType);

        /// <summary>返回 列表 </summary>
        /// <param name="whereFunc">
        /// Guid[] tempArray=new Guid[]{值1,值2}
        ///例：Query<T>(x => tempArray.Contains(x.字段)&&x.字段2=值2||x.字段3=值3);
        ///</param>
        ///<param name="suffix">分表后缀</param>
        IEnumerable<T> Query<T>(Expression<Func<T, bool>> whereFunc, string suffix, DbConnection cnn, DbTransaction tran, int? commandTimeout, Expression<Func<T, object>> fieldFunc);


        Task<IEnumerable<T>> QueryAsync<T>(Expression<Func<T, bool>> whereFunc, string suffix, DbConnection cnn, DbTransaction tran, int? commandTimeout, Expression<Func<T, object>> fieldFunc);

        /// <summary>
        /// 返回 指定表 单个实体数据
        /// </summary>
        T QueryModel<T>(Expression<Func<T, bool>> whereFunc, string suffix, DbConnection cnn, DbTransaction tran, int? commandTimeout, Expression<Func<T, object>> fieldFunc);




        /// <summary>
        /// 【此分页适用range分表原则（例按时间分表,按取值范围等）】 返回分表分页数据
        /// </summary>
        /// <exception cref="ArgumentNullException">分页参数为空抛出异常</exception>
        IEnumerable<T> QueryPage<T>(Expression<Func<T, bool>> whereFunc, RequestPageDTO requestPageDTO, string suffix, DbConnection cnn, DbTransaction tran, int? commandTimeout, Expression<Func<T, object>> fieldFunc, ref ResultPageDTO resultPageDTO);


        List<string> GetModelPkFields<T>();
        /// <summary>
        /// 表名是否存在；先从缓存中判断；再从数据库中判断
        /// </summary>
        /// <param name="fullTableName"></param>
        /// <param name="conn"></param>
        /// <param name="tran"></param>
        /// <returns></returns>

        bool IsExistsTable(string fullTableName, string schemaName, DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 表名是否存在于缓存中
        /// </summary>
        /// <param name="stuffName">分表标识</param>
        /// <returns>true:存在；false:不存在</returns>
        bool IsExistsTable<T>(T t, ref string stuffName);
        /// <summary>
        /// 所有业务表名
        /// </summary>
        List<string> FindAllModeTableNames(DbConnection conn, DbTransaction tran);

        /// <summary>
        /// 从   数据库   读取表结构生成
        /// </summary>
        Tables FindAllModelTableSchema(List<string> tableNames, DbConnection conn);
        /// <summary>
        /// 从   数据库   读取表结构生成
        /// </summary>
        Tables FindAllModelTableSchema(DbConnection conn);

        /// <summary>
        /// 从    模型文件    读取表结构
        /// </summary>
        Tables FindAllModelTableSchema(List<string> tableNames);
        /// <summary>
        ///从    模型文件    读取表结构
        /// </summary>
        Tables FindAllModelTableSchema();

        /// <summary>
        /// 创建表结构（仅结构）
        /// </summary>
        bool CreatTableSchema(string modelTableName, string stuff, string dataBaseName, string schemaName, DbConnection conn, DbTransaction tran);

        bool FullDBInitData(List<ModelInitData> modelInitDatas, DbConnection conn, DbTransaction tran);
        bool CreateDataBaseSchema(string dbFileDir, string databaseName, DbConnection conn);

        void CreateModelFile(Tables tables, DbConnection sqliteConn, DbTransaction tran);
        void CreateModelSchema(DbConnection sqliteConn, DbTransaction tran);

        /// <summary>
        /// 构建快速批量插入语句
        /// </summary>
        string GetBeatchInsertSql(DataTable dataTable, Dictionary<string, Type> fieldTypeDic, string fullTableName, string data_Fields);
    }
}
